iT邦幫忙

2024 iThome 鐵人賽

DAY 9
0
自我挑戰組

從零開始全端實作 Express.js + TypeScript + DevOps 系列 第 9

【Day 09】CSS 歷史與語法介紹(1)HTML 與 CSS 的配合

  • 分享至 

  • xImage
  •  

點我查看目錄

前言

在這環節中,我會以前兩天實做的 HTML 架構進行 CSS 的樣式表實做,進行美化排版。之前修過 UI / UX 的課程,發現這些視覺內容的呈現真的是很高深的學問,可能會讓人卻步,但實際上在實做中,我們只需要思考「如何呈現能讓重點更加突出?」或許這問題就會解決一半了,這一期內容就會來聊聊這部份。

究竟要先實做 CSS 還是 JavaScript?

這也是我在初學時,很好奇的一個問題。我們知道在前端開發中,有一個最重要的原則就是「關注點分離」。我們知道 HTML 是處理結構、CSS 是處理樣式、JavaScript 是處理行為。而實務上,樣式的呈現通常會比行為還更容易確定,因為 CSS 主要就是單純處理外觀問題,而在 JavaScript 實作互動設計時,經常就會涉及到較複雜的功能實做、以及前後端資料傳輸與邏輯處理等等的複雜情況。因此,如果我們先把基礎的 CSS 元素與外觀架構先實做出來,那後面就可以看著你要執行的**「實體」(物件)**進行 JavaScript 互動設計,這樣我們大腦就可以空出更多時間來思考互動實做,而不用一直花心思記得這個物件到底要做什麼了。

簡述 CSS 的發展與語法

A. HTML 與早期的網頁設計(1990 - 1994 年)

早期的 HTML 主要是為了在網頁中架設文件的結構,當時的語法對於外觀和樣式的控制其實相當有限。當時,網頁的樣式主要是透過 inline styles,也就是直接把樣式設定「嵌入」(Embed)到 HTML 標記中。可想而知,當我們要針對一個樣式做比較多控制的時候,就會發現該標記過於龐大且複雜,網頁工程師進行在座例行網頁維護工作時就會出現大麻煩了。

在 CSS 出現以前,當時為了控制網頁的外觀,網頁工程師只能夠過當時 HTML 1.0 中的樣式語法進行設定,例如 <font> 用來控制文字的字體大小和顏色、<center>用來將內容置中、而 <b><i> 用來顯示粗體或斜體文字。如果我們用當年 HTML 1.0 的語法,大概會像這樣:

<body>
  <center>
    <font face="Arial" size="5" color="red">
      <b><i>This is the Title</i></b>
    </font>
  </center>

  <p>
    <font face="Times New Roman" size="3" color="blue">
      <i>This is the blue text with Times New Roman font.</i>
    </font>
  </p>
</body>

畢竟每一個標記都是「逐項」設定的,就想像你要一次修改 200 個標記設定,那會有多刺激~

B. CSS 的構思與提出(1994 - 1996 年)

也正式因為如此,網頁的設計越來越複雜的時候,我們就會希望可以從一個固定的地方來控制網頁的樣式,讓呈現的網頁內文可以跟樣式分離。在當年的確有幾的除了 CSS 之外的解決方案,就是 DSSSL,但這語法複雜到不適合做簡單的網頁樣式設計。於是到 1994 年,當時一樣在 CERN 工作的 Håkon Wium Lie 就提出了 Cascading Style Sheets(CSS) 的構想,包含:

  • 樣式與內容分離:直接分離 HTML 的結構和呈現的樣式。
  • 階層樣式表:樣式是可以疊加的,便可以在全觀的樣式佈局之下,針對個案進行調整。
  • 樣式可重複使用:可以用一個樣式表控制多個頁面的樣式,這樣像是上面要一次修改 200 個標記的任務就可能可以簡化成改 5-10 個地方,相比之下就簡單多了。

這想法一提出就得到 W3C 鼎力支持。但瀏覽器開發廠商似乎就不是這樣想了~我們待會再說。

CSS 1.0


A. 剖析 CSS 規則集

CSS Anatomy.png
Source: https://developer.mozilla.org/en-US/docs/Learn/Getting_started_with_the_web/CSS_basics

  • 當時的 CSS 在語法撰寫上有這些名詞:

    • Selector:選擇器

      這是在 Ruleset 最前面的 HTML 標記名稱,用來定義我們要套用樣式的元素(在這個範例中,是 <p> 元素)。若你要控制其他標記的樣式,只需更改 Selector 即可。

    • Property:屬性

      這是你要定義 HTML 標記樣式的方式,在這個例子中,color<p> 標記的一個屬性。

    • Property Value:屬性值

      在冒號(:)的後面是 Property Value,決定某個屬性要被改成什麼樣式,而要被修改的標記屬性就是變成紅色。

    • Declaration:宣告

      這是一個「單一的」規則,就像上面的 color: red;,這樣 <p> 標記的內容是文字,也就是文字變成紅色了。單一宣告之間要用分號(;)隔開。

    • Ruleset:規則集

      所有該標記中的每個樣式 Declaration 的集合就是 Ruleset,必須用大括號 {} 包起來。

  • 當時有定義以下屬性:

    • 文字:控制字體大小、字體類型、顏色等(如 font-familyfont-size)。
    • 排版:如行高(line-height)、對齊(text-align)。
    • 盒子模型:邊距(margin)、內距(padding)和邊框(border
    • 背景屬性:包括背景顏色和背景圖片的設定。
    • 佈局控制:通過 floatclear 實現簡單的佈局控制。

B. 選擇器(Selectors)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Example of CSS Selector</title>
    <style>
	    ... [CSS Syntaxes Go Here]
    </style>
</head>
<body>
    <h1>This is Heading 1</h1>
    <h2>This is Heading 2</h2>
    <h3>This is Heading 3</h3>

    <div **id="header"**>
        <p>This paragraph is controlled by **ID Selector.**</p>
    </div>

    **<p>**This paragraph is controlled by **Element Selector.**</p>
    
    <p **class="example"**>This paragraph is controlled by **Class Selector.**</p>
</body>
</html>

當年的 CSS 1.0 只有最基礎的 Selector,我們用以上的 HTML 文件來看,看看下面的 CSS 對應到哪些標記:

  • Element(元素) Selector:對指定 HTML 元素應用樣式,如 ph1

    p {
        color: blue;
    }
    
  • Class Selector(類別):用 . 來選擇帶有特定 class 屬性的元素。

    .example {
        color: green;
    }
    
  • ID Selector:用 # 來選擇具有唯一 ID 的元素。

    #header {
        background-color: yellow;
    }
    
  • Group(群組)Selector:可以一次為多個元素應用相同的樣式,使用逗號分隔。

    h1, h2, h3 {
        color: red;
    }
    

B. 文字樣式(Text Styles)

CSS 1.0 提供了多種與文字樣式相關的屬性:

  1. 字體樣式

    • font-family:定義字體系列,我們可以設定很多字體做為備用。

      p {
          font-family: Arial, sans-serif;
      }
      
    • font-size:設定字體大小,方式有分為

      • 絕對單位:如 px(像素)、pt(點)。
      • 相對單位:如 em 或是 %,也就是相對於父元素(追溯到上一層級)的字體大小。
      #header p {
          font-size: 16px;
      }
      
    • font-style:設定字體樣式,如斜體(italic)。

      h1, h2, h3 {
          font-style: italic;
      }
      
    • font-weight:設定字體粗細,如加粗(bold)。

      p {
          font-weight: bold;
      }
      
  2. 文字顏色 color

    h1 {
        color: blue;
    }
    
  3. 文字對齊 text-align:如置中對齊(center)、靠左對齊(left)、靠右對齊(right)。

    #header {
        text-align: center;
    }
    
  4. 文字裝飾 text-decoration:如底線(underline)。

    h2 {
        text-decoration: underline;
    }
    
  5. 行高(間距)line-height

    p.example {
        line-height: 1.5;
    }
    

C. 顏色與背景(Colors and Backgrounds)

  • 背景顏色 background-color:你也可以在選擇器中寫 body 來控制整個頁面的顏色。

    p {
        background-color: lightgrey;
    }
    
  • 設定背景圖片 background-image

    body {
        background-image: url('background.jpg');
    }
    
  • 設定背景重複 background-repeat:選項有 repeat(重複)、no-repeat(不重複)、repeat-x(僅水平重複)和 repeat-y(僅垂直重複)。

    body {
        background-repeat: no-repeat;
    }
    
  • 設定背景位置 background-position:選項有 topcenterbottom 等。

    body {
        background-position: center;
    }
    

D. 盒子模型(Box Model)

CSS 1.0 引入了盒模型的概念,這是一個用來控制元素空間和邊距的核心機制,包括 marginpaddingborder 這些屬性:

  • Border(邊框):選項有 border-width(設定邊框寬度);border-style:(設定邊框樣式,如實線 solid、虛線 dashed);border-color:設定邊框顏色。

    p {
        border-width: 1px;
        border-style: solid;
        border-color: black;
    }
    
  • 內框距 padding:設定元素內部內容與內框之間的距離。

    p {
        padding: 10px;
    }
    
  • 外框距 margin:設定元素外部與其他元素(或外框)之間的距離。

    p {
        margin: 20px;
    }
    

E. Layout Control(佈局控制)

CSS 1.0 提供了簡單的佈局控制功能,主要通過 floatclear 來控制元素的排列:

  • 浮動 float:允許元素可以向左或向右移動,其他元素會圍繞 float 屬性的物件排列。

    img {
        float: left;
    }
    
  • 清除浮動 clear:用來控制元素如何清除浮動,選項包括 leftrightboth

    p {
        clear: both;
    }
    

F. 列表樣式(List Styles)

這裡包含設定無序列表(<ul>)和有序列表(<ol>)的樣式

  • 列表樣式類型 list-style-type:設定列表項目的符號樣式,如 disc(空心圓)、circle(實心圓)、square(方形)、或 decimal(數字)。

    ul {
        list-style-type: square;
    }
    
  • 列表樣式圖片 list-style-image:使用圖片作為列表符號。

    ul {
        list-style-image: url('bullet.png');
    }
    

從 CSS 1 到 CSS 2 的過渡(1997 - 1998 年)


Netscape 與 Microsoft 的競爭

在 1990 年代初期,Netscape Navigator 瀏覽器的市占率達到八成的壟斷程度,然而微軟在 1995 年推出 **Internet Explorer(IE)**開始攻佔市場。這兩間公司就開始進入「瀏覽器戰爭」。雖然在 CSS 推出後,Internet Explorer 3Netscape Navigator 4 都有支援一些 CSS 語法,但是當時他們各自希望建立的網頁生態圈 Netscape Layer 與 MS 的 VBScript 和 ActiveX,因此光是用開發的新技術來打架都來不及了,根本就不太花心思去開發 W3C 標準的 CSS。也正因如此,網頁工程師就必須要寫兩套 Code 來分別符合這兩家公司自己開發的標準,畢竟在他們各自的立場來看,如果規範統一了,那誰還要用我自家的瀏覽器?

這問題一直到 1998 年,當時網路社群的一些大老就開始發起 Web Standards Project(WaSP)的活動,主要在譴責這些瀏覽器廠商忽略這些標準的推動。而在這些使用者的「施壓」之下,才讓 Netscape 跟 Microsoft 開始妥協去接受 W3C 的 CSS 標準。後來我想他們也在統一規範之後,就讓開發環境變得輕鬆許多了吧~

CSS 1 本身限制

雖然 CSS 推出的時候得到廣泛支持,但畢竟做為第一代這種具有「實驗」性質的突破來說,很快就遇到不足的部份。這樣講太抽象了,舉一些具體案例:

  1. 如果果當時的網頁設計師,想要設計一個像報紙一樣的很多欄位的版面分配,他們必須使用巢狀的 <table> 標記進行實做,也就是表格內還有表格,這對當時的硬體資源相對薄弱而導致算力不足的網頁瀏覽器來說,可能就直接喝西北風了。雖然 CSS 1 的 float 屬性能讓元素自己浮動到旁邊,但在各欄位之間要上下對齊的時候就是一個大問題了,我想解決方式只有「合成圖片」了吧~
  2. 然後你會發現,合成圖片也是個問題。當年如果要做出現在有「圓角」或「陰影」的樣式效果,完全沒辦法實做,所以如果你想讓你的網頁美觀一些,你就要花時間自己去合成那些圖片,然後一個一個嵌入到 HTML 裡面。在當年還在撥接網路的時代,你把圖片放完要載入的時候,網頁可能要等好幾分鐘才會全部載完。然後客戶說一個「改」,你今天晚上就要加班了~
  3. 當時主流的瀏覽器布局設計會有兩個版本,針對螢幕顯示以及針對列印設計的內容布局。由於 CSS 1 並不支援不同裝置之間的佈局問題,你只能透過額外實做 HTML 或使用複雜的 JavaScript 來控制樣式的變化,光是看了就知道你工作量要加倍了。而且你會發現所有的樣式都無法在在一個地方集中管理,因為從外部引用 CSS 的完整功能到 HTML4 才出來。相同問題也出現在你想要在使用者在滑鼠停留在某個按鈕上時改變按鈕的顏色(現在很常見),但因為你缺少 :hover 這種 Pseudo-class 語法(我們後面 CSS 2 就會提到),所以你也只能用 JavaScript 進行實做,可想而知有多麻煩!
  4. 假設一位開發者在「瀏覽器戰爭」的背景下,他剛設計了一個非常簡單的網頁,只包含 和一些 ,他想用 paddingmargin 來調整 Box Model 的間距。但他發現在 IENetscape 上顯示的效果根本完全不同。Netscape 則根據 W3C 的標準進行渲染,但是當年 IE 的 Box Model 計算方式是錯誤的,因為 padding 跟 margin 竟然同時被拿來算元素的寬度,這就直接導致兩個瀏覽器下的佈局會直接走樣。所以你被主管要求要寫兩份 CSS 來處理相容性問題,你的 CSS 工作量就加倍了。

總結


基本上,CSS 1 的出現雖然在網頁設計歷史上算是一個重大突破,但仍無法當時在網頁實作上的需求,包含較為複雜布局、對不同界面要另外設計樣式、瀏覽器呈現的樣式也不一致...等,這些問題都讓 CSS 1 顯得相當不足,而這也讓 W3C 趕緊摧生出 CSS 2 來解決這些問題,基於 CSS 1 之上進行功能強化,對當時來說這樣的突破已經是「里程碑」了。而語法上,你會發現 CSS 的結構真的相當簡單,最困難的應該就是排版了吧~


上一篇
【Day 08】實作 2D 打磚小蜜蜂遊戲畫面的 HTML5 架構(2)
下一篇
【Day 10】CSS 歷史與語法介紹(2)CSS2 後續發展
系列文
從零開始全端實作 Express.js + TypeScript + DevOps 12
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言